<?php

namespace app\wxapp\service;

use app\common\model\Colloquial;
use app\common\model\VideoList;
use OSS\Core\OssException;
use OSS\OssClient;
use think\Exception;
use think\facade\Db;
use think\File;

/**
 * 管理的小程序端的声音上传
 * Class UploadService
 * @package app\wxapp\service
 */
class UploadService
{
    // 存储空间名称
    private $bucket = "medical-course";

    // Endpoint以杭州为例，其它Region请按实际情况填写。
    //$endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
    private $endpoint = "http://oss-cn-shenzhen.aliyuncs.com";

    private $urlHost = "https://medical-course.oss-cn-shenzhen.aliyuncs.com";

    // 阿里云主账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维，请登录 https://ram.console.aliyun.com 创建RAM账号。
    private $accessKeyId = "";
    private $accessKeySecret = "";

    private $ossClient;

    public function __construct()
    {
        $this->accessKeyId = env('aliyun.ali_access_key_id');
        $this->accessKeySecret = env('aliyun.ali_access_key_secret');
        $this->ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
    }


    /**
     * 上传口语测评语音
     * @param File $file
     * @param $videoId int 的id
     * @param $time
     * @param $uid int 用户id
     * @return mixed
     * @throws \Exception
     */
    public function uploadVoiceColloquial(File $file, $videoId, $time, $uid)
    {
        try {

            $video = VideoList::where(['id' => $videoId])->find();
            $outVideoId = $video['out_video_id'];

            //唯一的格式 因此如果是同一个视频的同一个位置 每个人只会有一份录音
            $basePath = "uploads/" . $outVideoId;
            $fileName = $uid . "_" . $time . "." . $file->extension();

            $info = $file->move(public_path($basePath), $fileName);
            // <yourObjectName>上传文件到OSS时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg
            // 设置文件名称。
            $object = $basePath . '/' . $fileName;

            //$object = "uploads/testimage.jpg";
            // <yourLocalFile>由本地文件路径加文件名包括后缀组成，例如/users/local/myfile.txt。
            $filePath = public_path() . $object;

            $this->ossClient->uploadFile($this->bucket, $object, $filePath);

            $exist = Colloquial::where(['out_video_id' => $outVideoId, 'time_position' => $time, 'uid' => $uid])->find();

            if (!$exist) {
                //保存
                return Colloquial::create([
                    'out_video_id' => $outVideoId,
                    'time_position' => $time,
                    'uid' => $uid,
                    'path' => $object
                ]);
            } else {
                return $exist;
            }
        } catch (\Exception $e) {
            throw new \Exception($e->getMessage());
            //throw new Exception($e->getTrace());
        }
    }

    /**
     * 上传口语测评语音 公众号的语音上传
     * @param $accessToken string
     * @param $mediaId string  微信服务器的语音文件id
     * @param $videoId int 的id
     * @param $sentenceId int 句子的id
     * @param $uid int 用户id
     * @return mixed
     * @throws \Exception
     */
    public function uploadVoiceColloquialMp($accessToken, $mediaId, $videoId, $sentenceId, $uid)
    {
        try {
            $url = "https://api.weixin.qq.com/cgi-bin/media/get?access_token=" . $accessToken . "&media_id=" . $mediaId;
            $fileContent = file_get_contents($url);
            //file_put_contents(public_path().'uploads/error_log.txt',$fileContent);
            $video = VideoList::where(['id' => $videoId])->find();
            $outVideoId = $video['out_video_id'];

            // 临时文件/云端目录
            $basePath = "uploads/" . $outVideoId;
            // 录音的原始文件
            $amrFile = public_path() . $basePath . '_' . $uid . "_" . $sentenceId . ".amr";
            // 录音的wav格式文件 如果是同一个视频的同一个位置 每个人只会有一份录音
            $fileName = $uid . "_" . $sentenceId . ".wav";
            // 云端完整文件名
            $object = $basePath . '_' . $fileName;
            // 临时目录完整文件名
            $fileDir = public_path() . "uploads/kouyulianxi/{$videoId}/";
            $filePath = $fileDir . "{$outVideoId}_{$uid}_{$sentenceId}.wav";
            // 目录不存在则创建
            if (!is_dir($fileDir)) {
                mkdir($fileDir, 0755, true);
            }

            // 保存录音文件
            file_put_contents($amrFile, $fileContent);
            // 通过接口转换格式 amr -> wav
            if (!$this->audioTransformation($amrFile, $filePath)) {
                throw new \Exception('录音解析失败');
            }

            // 录音文件上传到oss
            $this->ossClient->uploadFile($this->bucket, $object, $filePath);
            // 清除本地临时文件
            @unlink($amrFile);
//            @unlink($filePath);

            $exist = Colloquial::where(['out_video_id' => $outVideoId, 'sentence_id' => $sentenceId, 'uid' => $uid])->find();

            if (!$exist) {
                //保存
                return Colloquial::create([
                    'out_video_id' => $outVideoId,
                    'sentence_id' => $sentenceId,
                    'uid' => $uid,
                    'path' => $object,
                ]);
            } else {
                return $exist;
            }
        } catch (\Exception $e) {
            file_put_contents(public_path() . 'uploads/error_log.txt', $e->getMessage());
            throw new \Exception($e->getMessage());
            //throw new Exception($e->getTrace());
        }
    }

    /**
     * 将amr文件转换成wav文件
     * @param string $from 本地文件绝对路径
     * @param string $to 转换后的本地文件路径
     * @return bool
     */
    protected function audioTransformation($from, $to)
    {
        $curl = curl_init('https://s19.aconvert.com/convert/convert-batch.php');
        curl_setopt_array($curl, [
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => 0,
            CURLOPT_POST => 1,
            CURLOPT_POSTFIELDS => [
                'targetformat' => 'wav',
                'audiobitratetype' => '0',
                'customaudiobitrate' => '',
                'audiosamplingtype' => '0',
                'customaudiosampling' => '',
                'code' => '82000',
                'filelocation' => 'local',
                'file' => new \CURLFile($from),
            ]
        ]);
        $data = curl_exec($curl);
        $error = curl_error($curl);
        curl_close($curl);

        return !($error
            || !$data
            || !($data = json_decode($data))
            || 'SUCCESS' !== $data->state
            || empty($data->filename)
            || false === file_put_contents($to, file_get_contents("https://s{$data->server}.aconvert.com/convert/p3r68-cdx67/{$data->filename}"))
        );
    }


    /**
     * 上传声音评论
     */
    public function uploadVoiceComment()
    {

    }


    /**
     * 删除图片
     * 图片路径
     * @param $object
     * @return boolean
     */
    public function delete($object)
    {
        try {
            $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
            $ossClient->deleteObject($this->bucket, $object);
        } catch (OssException $e) {
            return false;
        }
        return true;
    }
}